#ifndef _INTS_H_
#define _INTS_H_

#include <dpmi.h>
#include <go32.h>
#include "utypes.h"


/** @defgroup Interrupts Interrupts
 * @{
 *
 * Interrupt related functions
 */

/** @name PIC registers address */
/*@{*/ 
#define EOI       0x20  ///< End Of Interrupt Command */
#define PIC1_CMD  0x20  ///< PIC1 register address to send EOI */
#define PIC2_CMD  0xA0  ///< PIC2 register address to send EOI */
#define PIC1_MASK 0x21  ///< PIC1 register address to read/write interrupt mask */
#define PIC2_MASK 0xA1  ///< PIC2 register address to read/write interrupt mask */
/*@}*/ 


/** @name PC Interrupts */
/*@{*/
#define T0_IRQ    0  ///< Timer 0       
#define KBD_IRQ   1  ///< keyboard       
#define COM2_IRQ  3  ///< serial port 2 
#define COM1_IRQ  4  ///< serial port 1  
#define FLP_IRQ   6  ///< floppy         
#define LPT_IRQ   7  ///< parallel port  
#define RTC_IRQ   8  ///< realtime clock 
#define MOUSE_IRQ 12 ///< mouse          
#define FPU_IRQ   13 ///< Floating point 
#define DISK1_IRQ 14 ///< Hard disk controller 1   
#define DISK2_IRQ 15 ///< Hard disk controller 2   
/*@}*/ 

/** @name Some usefull definitions */
/*@{*/
/** Gives mask bit associated with a given irq.
 * <em>Warning</em>, if irq > 7 the result must be applied to PIC2
 */
#define IRQ_MASK_BIT(irq) ((irq) < 8 ? 1 << (irq) : (1 << (irq)) >> 8)

/** gives the vector associated with a given IRQ */
#define IRQ_VECTOR(irq) ((irq) < 8 ? (irq) + 0x08 : (irq) - 8 + 0x70)
/*@}*/

void temp_asm(void);

/**
 * Instala a fun��o 'irq_func', escrita em Assembly, como o
 * handler das interrupcoes associado a interrupcao 'irq',
 * actualizando a estrutura 'old_irq' com o handler de
 * interrupcoes actual.
 * @return 0
 *
 * @param irq Interrupcao
 * @param irq_func(void) Funcao escrita em Assembley a ser instalada
 * @param old_irq Estrutura a ser actualizada
 */
int install_asm_irq_handler(int irq, void (*irq_func)(void),
			    _go32_dpmi_seginfo *old_irq);

/**
 * Instala a funcao 'irq_func', escrita em C, como o handler
 * das interrupcoes associado a interrupcao 'irq',
 * actualizando a estrtura 'old_irq' com o handler de
 * interrupcoes actual.
 * @return 0
 *
 * @param irq Interrupcao
 * @param irq_func(void) Funcao escrita em C a ser instalada
 * @param old_irq Estrutura a ser actualizada
 */
int install_c_irq_handler(int irq, void (*irq_func)(void),
			    _go32_dpmi_seginfo *old_irq);

/**
 * Reinstala o handler das interrupcoes especificado em
 * 'old_irq' para interrupcoes 'irq'.
 * @param irq Interrupcao
 * @param old_irq Interrupcao a ser reinstalada
 */
void reinstall_asm_irq_handler(int irq, _go32_dpmi_seginfo *old_irq);

/**
 * Reinstala o handler das interrupcoes especificado em
 * 'old_irq' para interrupcoes 'irq'.
 * @param irq Interrupcao
 * @param old_irq Interrupcao a ser reinstalada
 */
void reinstall_c_irq_handler(int irq, _go32_dpmi_seginfo *old_irq);

/**
 * Desabilita a interrupcao IRQ.
 * @return 'pic' anterior
 *
 * @param irq Interrupcao
 */
int disable_irq(int irq);

/**
 * Habilita a interrupcao IRQ.
 * @param irq Interrupcao
 */
void enable_irq(int irq);

/**
 * Desabilita as interrupcoes globais.
 */
void disable_int();

/**
 * Habilita as interrupcoes globais.
 */
void enable_int();

/** @} end of interrupts */

#endif
